package com.example.serviceconsumer.service;

import com.example.serviceconsumer.client.ProductClientA;
import com.example.serviceconsumer.client.ProductClientB;
import com.example.serviceconsumer.model.Product;
import io.github.resilience4j.bulkhead.ThreadPoolBulkhead;
import io.github.resilience4j.bulkhead.annotation.Bulkhead;
import io.github.resilience4j.circuitbreaker.annotation.CircuitBreaker;
import io.github.resilience4j.ratelimiter.annotation.RateLimiter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.function.Supplier;

@Service
public class ProductResilienceService {

    @Qualifier("com.example.serviceconsumer.client.ProductClientA")
    @Autowired
    private ProductClientA productClientA;

    @Qualifier("com.example.serviceconsumer.client.ProductClientB")
    @Autowired
    private ProductClientB productClientB;

    @Autowired
    private ThreadPoolBulkhead threadPoolBulkhead;

    // --- 方法1：应用断路器A(失败率阈值30%) ---
    @CircuitBreaker(name = "backendA", fallbackMethod = "getAllProductsFallback")
    public ResponseEntity<List<Product>> getAllProductsProtected() {
        return productClientA.getAllProducts();
    }

    // --- 方法2：应用断路器B(失败率50%+慢调用30%) ---
    @CircuitBreaker(name = "backendB", fallbackMethod = "getProductByIdFallback")
    public ResponseEntity<Product> getProductByIdProtected(Long id) {
        return productClientB.getProductById(id);
    }

    // --- 方法3：应用隔离器 (Bulkhead) 限制并发数和最大等待时间 ---
    @Bulkhead(name = "backendC", fallbackMethod = "getAllProductsFallbackForBulkhead")
    public ResponseEntity<List<Product>> getAllProductsWithBulkhead() {
        return productClientA.getAllProducts();
    }

    // --- 新增：隔离器专用测试方法(不经过断路器) ---
    @Bulkhead(name = "backendC", type = Bulkhead.Type.SEMAPHORE, fallbackMethod = "getBulkheadTestFallback")
    public ResponseEntity<String> testBulkheadOnly() {
        // 模拟一个耗时操作来测试隔离器
        System.out.println("信号量隔离器方法执行开始: 线程 " + Thread.currentThread().getName());
        try {
            Thread.sleep(300); // 模拟300ms的处理时间
            System.out.println("信号量隔离器方法执行完成: 线程 " + Thread.currentThread().getName());
            return ResponseEntity.ok("隔离器测试成功: 当前线程 " + Thread.currentThread().getName());
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new RuntimeException("线程中断", e);
        }
    }

    // --- 方法4：应用限流器 (RateLimiter) 限制调用频率 ---
    @RateLimiter(name = "backendD", fallbackMethod = "getProductByIdFallbackForRateLimiter")
    public ResponseEntity<Product> getProductByIdWithRateLimiter(Long id) {
        return productClientB.getProductById(id);
    }

    // --- 新增：使用线程池隔离器的异步方法 ---
    public CompletableFuture<String> testThreadPoolBulkhead() {
        System.out.println("开始处理请求，当前线程: " + Thread.currentThread().getName());
        
        Supplier<String> supplier = () -> {
            System.out.println("隔离器内部执行，线程: " + Thread.currentThread().getName());
            try {
                Thread.sleep(1000); // 模拟处理时间
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return "处理被中断";
            }
            return "隔离器测试成功 - 线程: " + Thread.currentThread().getName();
        };

        return threadPoolBulkhead.executeSupplier(supplier)
                .handle((result, throwable) -> {
                    if (throwable != null) {
                        System.err.println("隔离器拒绝请求: " + throwable.getMessage());
                        return "隔离器降级: 请求被拒绝";
                    }
                    return result;
                })
                .toCompletableFuture();
    }

    // --- Fallback 方法 ---

    // 断路器A的降级方法
    public ResponseEntity<List<Product>> getAllProductsFallback(Throwable t) {
        System.err.println("断路器A降级: getAllProducts触发 - " + t.getClass().getName());
        List<Product> defaultList = new ArrayList<>();
        defaultList.add(new Product(-1L, "断路器A降级: 服务不可用(失败率>30%)", 0.0));
        return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE).body(defaultList);
    }

    // 断路器B的降级方法
    public ResponseEntity<Product> getProductByIdFallback(Long id, Throwable t) {
        System.err.println("断路器B降级: getProductById(" + id + ")触发 - " + t.getClass().getName());
        return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE)
                .body(new Product(id, "断路器B降级: 服务不可用(失败率>50%或慢调用>30%)", 0.0));
    }

    // 隔离器的降级方法
    public ResponseEntity<List<Product>> getAllProductsFallbackForBulkhead(Throwable t) {
        System.err.println("隔离器降级: getAllProductsWithBulkhead触发 - " + t.getClass().getName());
        List<Product> defaultList = new ArrayList<>();
        defaultList.add(new Product(-1L, "隔离器降级: 并发限制(最大10个,等待20ms)", 0.0));
        return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE).body(defaultList);
    }

    // 限流器的降级方法
    public ResponseEntity<Product> getProductByIdFallbackForRateLimiter(Long id, Throwable t) {
        System.err.println("限流器降级: getProductByIdWithRateLimiter(" + id + ")触发 - " + t.getClass().getName());
        return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE)
                .body(new Product(id, "限流器降级: 流量限制(2秒内最多5个请求)", 0.0));
    }

    // 隔离器专用测试的降级方法
    public ResponseEntity<String> getBulkheadTestFallback(Throwable t) {
        System.err.println("信号量隔离器降级: " + t.getClass().getName() + " - " + t.getMessage());
        return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE)
                .body("信号量隔离器降级: 并发超限");
    }

}